#include "ImagesLoadThread.h"
#include <QtCore/QEvent>
#include <QtCore/QCoreApplication>
#include <QtGui/QImageReader>
#include <QtCore/QDebug>

class ImageLoadEvent:public QEvent
{
public:
	static QEvent::Type EventType() {
		return QEvent::Type(QEvent::User+111);
	}
	ImageLoadEvent(const QString& imgFilePath,const QSize& size)
		:QEvent(EventType()),_filePath(imgFilePath),_size(size)
	{
	}
	virtual ~ImageLoadEvent(){}
	QString filePath() const{
		return _filePath;
	}	
	QSize size() const{
		return _size;
	}
private:
	const QString _filePath;
	const QSize   _size;
};

class ImageLoader:public QObject
{
public:
	ImageLoader(ImagesLoadThread* loadThread)
		:_loadThread(loadThread)
	{
	}

	virtual void customEvent ( QEvent * event ) override{
		if ((int)event->type()==ImageLoadEvent::EventType()){
			ImageLoadEvent* evt=static_cast<ImageLoadEvent*>(event);
			QImage image=loadImage(evt->filePath(),evt->size());
			if (image.isNull()){
				static QImage failedImage(":/imgs/failed.PNG");
				image=failedImage;
			}
			_loadThread->emitImageLoaded(image,evt->filePath());
		}else{
			QObject::customEvent(event);
		}
	}

private:
	QImage loadImage(const QString& filePath,const QSize& size){
		qDebug()<<"Load image "<<filePath<<" in thread!\n";
		QImageReader imgReader(filePath);
		imgReader.setQuality(10);
		QSize imgSize(imgReader.size());
		if (imgSize.isValid()){
			if (imgSize.width()>size.width() || imgSize.height()>size.height()){
				imgSize.scale(size,Qt::KeepAspectRatio);
				imgReader.setScaledSize(imgSize);
			}
		}
		return imgReader.read();
	}

	ImagesLoadThread* _loadThread;
};


ImagesLoadThread::ImagesLoadThread(QObject *parent)
	: QThread(parent),_imageLoader(0)
{
	this->start();
}

ImagesLoadThread::~ImagesLoadThread()
{
	this->quit();
	this->wait();
}

void ImagesLoadThread::run(){
	_imageLoader=new ImageLoader(this);
	this->exec();
	delete _imageLoader;
	_imageLoader=0;
}

void ImagesLoadThread::startLoad(const QString& imgFilePath,const QSize& size){
	if (_imageLoader){
		qDebug()<<"Require loading "<<imgFilePath<<"\n";
		QCoreApplication::postEvent(_imageLoader,new ImageLoadEvent(imgFilePath,size));
	}
}

void ImagesLoadThread::cancelAllLoading(){
	if (_imageLoader){
		QCoreApplication::removePostedEvents(_imageLoader,ImageLoadEvent::EventType());
	}
}

void ImagesLoadThread::emitImageLoaded(const QImage& image,const QString& filePath){
	qDebug()<<"Emit image loaded "<<filePath<<"\n";
	emit imageLoaded(image,filePath);
}

